package com.leyou.item.service;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.item.pojo.Stock;
import com.leyou.pojo.PageResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AmqpTemplate amqpTemplate;


    private static final Logger logger = LoggerFactory.getLogger(GoodsService.class);


    /**
     * 商品列表分页查询
     *
     * @param key
     * @param saleable
     * @param page
     * @param rows
     * @return
     */
    public PageResult<SpuBo> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {

        PageHelper.startPage(page, rows);

        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //TODO 逻辑删除 此处添加一个查询条件,只查valid为1的
        criteria.andEqualTo("valid", true);

        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        if (null != saleable) {
            criteria.andEqualTo("saleable", saleable);
        }

        Page<Spu> pageInfo = (Page<Spu>) this.spuMapper.selectByExample(example);

        List<SpuBo> spuBoList = new ArrayList<>();
        pageInfo.forEach(spu -> {
            SpuBo spuBo = new SpuBo();
            BeanUtils.copyProperties(spu, spuBo);

            String bname = this.brandService.queryNameById(spu.getBrandId());

            spuBo.setBname(bname);

            List<String> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

            spuBo.setCname(StringUtils.join(names, "/"));

            spuBoList.add(spuBo);
        });

        return new PageResult<>(pageInfo.getTotal(), new Long(pageInfo.getPages()), spuBoList);
    }


    /**
     * 商品管理页新增商品
     *
     * @param spu
     */
    @Transactional
    public void saveGoods(SpuBo spu) {
        //保存spu
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(spu.getCreateTime());
        spu.setValid(true);
        spu.setSaleable(true);

        this.spuMapper.insertSelective(spu);

        //保存spu_detail
        SpuDetail spuDetail = spu.getSpuDetail();
        spuDetail.setSpuId(spu.getId());

        this.spuDetailMapper.insertSelective(spuDetail);

        //保存sku
        List<Sku> skus = spu.getSkus();
        saveSkuAndStock(skus, spu.getId());


        sendMessage(spu.getId(), "insert");
    }


    /**
     * 从新增商品和修改商品中 抽调出来 保存库存
     *
     * @param skus
     * @param spuId
     */
    private void saveSkuAndStock(List<Sku> skus, Long spuId) {

        for (Sku sku : skus) {
            if (!sku.getEnable()) {
                continue;
            }
            sku.setSpuId(spuId);
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());

            this.skuMapper.insertSelective(sku);

            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());

            this.stockMapper.insertSelective(stock);
        }
    }

    /**
     * 商品列表修改商品 根据spuId查询对应的spuDetail 回显数据到前台页面
     *
     * @param spuId
     * @return
     */
    public SpuDetail querySpuDetailById(Long spuId) {
        return this.spuDetailMapper.selectByPrimaryKey(spuId);
    }


    /**
     * 商品列表页 修改商品 根据spuId查询对应的skus 回显数据到前台页面
     *
     * @param spuId
     * @return
     */
    public List<Sku> querySkuBySpuId(Long spuId) {
        Sku record = new Sku();
        record.setSpuId(spuId);

        List<Sku> skus = this.skuMapper.select(record);

        skus.forEach(sku -> sku.setStock(this.stockMapper.selectByPrimaryKey(sku.getId()).getStock()));

        return skus;
    }


    /**
     * 商品列表页 修改商品
     *
     * @param spu
     */
    @Transactional
    public void updateGoods(SpuBo spu) {
        //对spu和spudetail直接进行更新
        spu.setLastUpdateTime(new Date());
        this.spuMapper.updateByPrimaryKeySelective(spu);

        this.spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail());

        //处理sku三种情况
        Sku recode = new Sku();
        recode.setSpuId(spu.getId());
        List<Sku> dbSkus = this.skuMapper.select(recode);//数据库中的旧数据

        List<Sku> newSkus = spu.getSkus();
        newSkus.forEach(newSku -> {
            if (null == newSku.getId()) {//新数据中id为null的直接添加到数据库中
                newSku.setCreateTime(new Date());
                newSku.setLastUpdateTime(newSku.getCreateTime());
                newSku.setSpuId(spu.getId());

                this.skuMapper.insertSelective(newSku);

                Stock stock = new Stock();
                stock.setSkuId(newSku.getId());
                stock.setStock(newSku.getStock());

                this.stockMapper.insertSelective(stock);
            } else { //新数据中有id的进行更新,更新后删除旧数据集合中id相同的数据
                newSku.setLastUpdateTime(new Date());
                newSku.setSpuId(spu.getId());

                this.skuMapper.updateByPrimaryKeySelective(newSku);

                Stock stock = new Stock();
                stock.setSkuId(newSku.getId());
                stock.setStock(newSku.getStock());

                this.stockMapper.updateByPrimaryKeySelective(stock);

                dbSkus.removeIf(obj -> obj.getId().equals(newSku.getId()));
            }
        });


        //对剩下的旧数据进行迭代,全部下架处理
        dbSkus.forEach(dbSku -> {
            dbSku.setEnable(false);
            this.skuMapper.updateByPrimaryKeySelective(dbSku);
        });

        sendMessage(spu.getId(), "update");
    }


    /**
     * 商品列表上下架按钮点击事件
     *
     * @param spuId 改变上下架状态的spu id
     * @return 状态码
     */
    public void isSaleableBySpuId(Long spuId) {
        this.spuMapper.isSaleableBySpuId(spuId);
    }


    /**
     * 商品列表删除按钮点击事件
     *
     * @param spuId
     * @return
     */
    @Transactional
    public Boolean isDeleteBySpuId(Long spuId) {
        int isSaleable = this.spuMapper.querySaleableBySpuId(spuId);
        if (isSaleable == 0) {
            int i = this.spuMapper.isDeleteBySpuId(spuId);
            return i != 0;
        }
        return false;
    }


    /**
     * 根据spu的id查询spu
     *
     * @param spuId
     * @return
     */
    public Spu querySpuById(Long spuId) {
        return this.spuMapper.selectByPrimaryKey(spuId);
    }


    /**
     * 消息发送器
     *
     * @param id
     * @param type
     */
    private void sendMessage(Long id, String type) {
        // 发送消息
        try {
            this.amqpTemplate.convertAndSend("item." + type, id);
        } catch (Exception e) {
            logger.error("{}商品消息发送异常，商品id：{}", type, id, e);
        }
    }
}
